package net.interneteidee.dao;

import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.UniqueConstraint;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.xml.bind.annotation.XmlTransient;

@Stateless
public class GenericDao<T> {

	@PersistenceContext(unitName = "primary")
	protected EntityManager entityManager;

	protected CriteriaBuilder criteriaBuilder;
	protected CriteriaQuery<T> criteriaQuery;
	protected Root<T> root;

	private Class subClass;

	public GenericDao() {
		// TODO Auto-generated constructor stub

	}

	public GenericDao(Class subClass) {
		// TODO Auto-generated constructor stub
		this.subClass = subClass;
		

	}

	@PostConstruct
	public void initCriteriaAttributi() {
		criteriaBuilder = entityManager.getCriteriaBuilder();

	}

	/**
	 * Metodo usato per il salvataggio di una entità
	 * 
	 * @param entity
	 */
	public void save(T entity) {
		entityManager.persist(entity);

	}

	/**
	 * Metodo utilizzato per l'aggiornamento di una entità detatched
	 * 
	 * @param entity
	 */
	public void update(T entity) {
		entityManager.merge(entity);
	}

	/**
	 * Metodo utilizzato per l' eliminazione di una entità detached
	 * 
	 * @param entity
	 */
	public void remove(T entity) {
		entityManager.remove(entity);
	}

	/**
	 * Cerca una entita in base all' id , subClass indica il tipo di entita da
	 * cercare
	 * 
	 * @param id
	 */
	public T findById(long id) {
		
	
		return (T) entityManager.find(subClass, id);
		
	}
	
	public T findByCodice(String nameParam,long codice){
		
		String stringQuery = "from "+subClass.getName()+" where "+nameParam+"="+codice;
		Query query = entityManager.createQuery(stringQuery);
		
		if(query.getResultList().size()==0)
			return null;
		else
			return (T) query.getSingleResult();
		
	
	}
	
	

	/**
	 * Cerca tutte le entita di un dato tipo definito da subclass
	 * 
	 * @return
	 */
	public List<T> findAll() {
		return entityManager.createQuery("from "+subClass.getName()).getResultList();
	}
	
	public boolean  checkIfManaged(T entity){
		return entityManager.contains(entity);
	}


	public Class getSubClass() {
		return subClass;
	}

	public void setSubClass(Class subClass) {
		this.subClass = subClass;
	}
	
	

}
